home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Language/OS - Multiplatform Resource Library
/
LANGUAGE OS.iso
/
gnu
/
nethack.lha
/
nethack-3.1
/
src
/
wield.c
< prev
next >
Wrap
C/C++ Source or Header
|
1993-01-24
|
8KB
|
283 lines
/* SCCS Id: @(#)wield.c 3.1 92/12/10 */
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
/* NetHack may be freely redistributed. See license for details. */
#include "hack.h"
/* elven weapons vibrate warningly when enchanted beyond a limit */
#define is_elven_weapon(optr) ((optr)->otyp == ELVEN_ARROW\
|| (optr)->otyp == ELVEN_SPEAR\
|| (optr)->otyp == ELVEN_DAGGER\
|| (optr)->otyp == ELVEN_SHORT_SWORD\
|| (optr)->otyp == ELVEN_BROADSWORD\
|| (optr)->otyp == ELVEN_BOW)
/* Note: setuwep() with a null obj, and uwepgone(), are NOT the same! Sometimes
* unwielding a weapon can kill you, and lifesaving will then put it back into
* your hand. If lifesaving is permitted to do this, use
* setwuep((struct obj *)0); otherwise use uwepgone().
*/
void
setuwep(obj)
register struct obj *obj;
{
setworn(obj, W_WEP);
/* Note: Explicitly wielding a pick-axe will not give a "bashing"
* message. Wielding one via 'a'pplying it will.
*/
if (obj)
unweapon = ((obj->otyp >= BOW || obj->otyp <= BOOMERANG) &&
obj->otyp != PICK_AXE && obj->otyp != UNICORN_HORN);
else
unweapon = TRUE; /* for "bare hands" message */
}
void
uwepgone()
{
if (uwep) {
setnotworn(uwep);
unweapon = TRUE;
}
}
static const char NEARDATA wield_objs[] =
{ ALL_CLASSES, ALLOW_NONE, WEAPON_CLASS, TOOL_CLASS, 0 };
int
dowield()
{
register struct obj *wep;
register int res = 0;
multi = 0;
#ifdef POLYSELF
if (cantwield(uasmon)) {
pline("Don't be ridiculous!");
return(0);
}
#endif
if (!(wep = getobj(wield_objs, "wield"))) /* nothing */;
else if (uwep == wep)
You("are already wielding that!");
else if (welded(uwep))
weldmsg(uwep, TRUE);
else if (wep == &zeroobj) {
if (uwep == 0)
You("are already empty %s.", body_part(HANDED));
else {
You("are empty %s.", body_part(HANDED));
setuwep((struct obj *) 0);
res++;
}
} else if (!uarmg &&
#ifdef POLYSELF
!resists_ston(uasmon) &&
#endif
(wep->otyp == CORPSE && wep->corpsenm == PM_COCKATRICE)) {
/* Prevent wielding cockatrice when not wearing gloves --KAA */
You("wield the cockatrice corpse in your bare %s.",
makeplural(body_part(HAND)));
# ifdef POLYSELF
if (!(poly_when_stoned(uasmon) && polymon(PM_STONE_GOLEM)))
# endif
{
You("turn to stone...");
killer_format = KILLED_BY;
killer="touching a cockatrice corpse";
done(STONING);
}
} else if (uarms && bimanual(wep))
You("cannot wield a two-handed %s while wearing a shield.",
is_sword(wep) ? "sword" :
wep->otyp == BATTLE_AXE ? "axe" : "weapon");
else if (wep->owornmask & (W_ARMOR | W_RING | W_AMUL | W_TOOL))
You("cannot wield that!");
else if (!wep->oartifact || touch_artifact(wep,&youmonst)) {
res++;
if (wep->cursed &&
(wep->oclass == WEAPON_CLASS ||
wep->otyp == HEAVY_IRON_BALL || wep->otyp == PICK_AXE ||
wep->otyp == UNICORN_HORN || wep->otyp == TIN_OPENER)) {
const char *tmp = xname(wep), *thestr = "The ";
if (strncmp(tmp, thestr, 4) && !strncmp(The(tmp),thestr,4))
tmp = thestr;
else tmp = "";
pline("%s%s %s to your %s!",
tmp, aobjnam(wep, "weld"),
(wep->quan == 1L) ? "itself" : "themselves", /* a3 */
body_part(HAND));
wep->bknown = TRUE;
} else {
/* The message must be printed before setuwep (since
* you might die and be revived from changing weapons),
* and the message must be before the death message and
* Lifesaved rewielding. Yet we want the message to
* say "weapon in hand", thus this kludge.
*/
long dummy = wep->owornmask;
wep->owornmask |= W_WEP;
prinv(NULL, wep, 0L);
wep->owornmask = dummy;
}
setuwep(wep);
}
return(res);
}
void
erode_weapon(acid_dmg)
boolean acid_dmg;
/* Rust weapon, or corrode it if acid damage is called for */
{
if(!uwep || uwep->oclass != WEAPON_CLASS) return; /* %% */
if (uwep->greased) {
grease_protect(uwep,NULL,FALSE);
} else if(uwep->oerodeproof ||
(acid_dmg ? !is_corrodeable(uwep) : !is_rustprone(uwep))) {
if (flags.verbose || !(uwep->oerodeproof && uwep->rknown))
Your("%s not affected.", aobjnam(uwep, "are"));
if (uwep->oerodeproof) uwep->rknown = TRUE;
} else if (uwep->oeroded < MAX_ERODE) {
Your("%s%s!", aobjnam(uwep, acid_dmg ? "corrode" : "rust"),
uwep->oeroded+1 == MAX_ERODE ? " completely" :
uwep->oeroded ? " further" : "");
uwep->oeroded++;
} else
if (flags.verbose)
Your("%s completely %s.",
aobjnam(uwep, Blind ? "feel" : "look"),
acid_dmg ? "corroded" : "rusty");
}
int
chwepon(otmp, amount)
register struct obj *otmp;
register int amount;
{
register const char *color = Hallucination ? hcolor() :
(amount < 0) ? Black : blue;
register const char *xtime;
if(!uwep || (uwep->oclass != WEAPON_CLASS && uwep->otyp != PICK_AXE
&& uwep->otyp != UNICORN_HORN)) {
char buf[36];
Sprintf(buf, "Your %s %s.", makeplural(body_part(HAND)),
(amount >= 0) ? "twitch" : "itch");
strange_feeling(otmp, buf);
exercise(A_DEX, amount >= 0);
return(0);
}
if(uwep->otyp == WORM_TOOTH && amount >= 0) {
uwep->otyp = CRYSKNIFE;
Your("weapon seems sharper now.");
uwep->cursed = 0;
return(1);
}
if(uwep->otyp == CRYSKNIFE && amount < 0) {
uwep->otyp = WORM_TOOTH;
Your("weapon seems duller now.");
return(1);
}
if (amount < 0 && uwep->oartifact && restrict_name(uwep, ONAME(uwep))) {
if (!Blind)
Your("%s %s.", aobjnam(uwep, "faintly glow"), color);
return(1);
}
/* there is a (soft) upper and lower limit to uwep->spe */
if(((uwep->spe > 5 && amount >= 0) || (uwep->spe < -5 && amount < 0))
&& rn2(3)) {
if (!Blind)
Your("%s %s for a while and then evaporate%s.",
aobjnam(uwep, "violently glow"), color,
uwep->quan == 1L ? "s" : "");
else
Your("%s.", aobjnam(uwep, "evaporate"));
while(uwep) /* let all of them disappear */
/* note: uwep->quan = 1 is nogood if unpaid */
useup(uwep);
return(1);
}
if (!Blind) {
xtime = (amount*amount == 1) ? "moment" : "while";
Your("%s %s for a %s.",
aobjnam(uwep, amount == 0 ? "violently glow" : "glow"),
color, xtime);
}
uwep->spe += amount;
if(amount > 0) uwep->cursed = 0;
/*
* Enchantment, which normally improves a weapon, has an
* addition adverse reaction on Magicbane whose effects are
* spe dependent. Give an obscure clue here.
*/
if (uwep->oartifact == ART_MAGICBANE && uwep->spe >= 0) {
Your("right %s %sches!",
body_part(HAND),
(((amount > 1) && (uwep->spe > 1)) ? "flin" : "it"));
}
/* an elven magic clue, cookie@keebler */
if ((uwep->spe > 5)
&& (is_elven_weapon(uwep) || uwep->oartifact || !rn2(7)))
Your("%s unexpectedly.",
aobjnam(uwep, "suddenly vibrate"));
return(1);
}
int
welded(obj)
register struct obj *obj;
{
if (obj && obj == uwep && obj->cursed &&
(obj->oclass == WEAPON_CLASS ||
obj->otyp == HEAVY_IRON_BALL ||
obj->otyp == TIN_OPENER || obj->otyp == PICK_AXE ||
obj->otyp == UNICORN_HORN))
{
obj->bknown = TRUE;
return 1;
}
return 0;
}
/* The reason for "specific" is historical; some parts of the code used
* the object name and others just used "weapon"/"sword". This function
* replaced all of those. Which one we use is really arbitrary.
*/
void
weldmsg(obj, specific)
register struct obj *obj;
boolean specific;
{
char buf[BUFSZ];
if (specific) {
long savewornmask = obj->owornmask;
obj->owornmask &= ~W_WEP;
Strcpy(buf, Doname2(obj));
obj->owornmask = savewornmask;
} else
Sprintf(buf, "Your %s%s",
is_sword(obj) ? "sword" : "weapon",
plur(obj->quan));
Strcat(buf, (obj->quan == 1L) ? " is" : " are");
#ifdef POLYSELF
Sprintf(eos(buf), " welded to your %s!",
bimanual(obj) ? (const char *)makeplural(body_part(HAND)) : body_part(HAND));
#else
Sprintf(eos(buf), " welded to your hand%s!",
bimanual(obj) ? "s" : "");
#endif
pline(buf);
}
/*wield.c*/